import pylab, pickle;
from PyQt4 import QtCore;

class InterfaceAPI():
    def __init__(self, parent):
        self.parent = parent;
        self.mainWin = parent.mainWin;
        self.graphScene = parent.graphScene;
        self.graphView = parent.graphScene.graphView;
        self.dataModel = parent.dataContainer.dataModel;
        self.dataView = parent.dataContainer.dataView;
        self.dataContainer = parent.dataContainer;
        self.receivedData = [];
        self.allCmds = ["animTrans", "setStateType", "setActionType", "showTrans", 
                 "regenerateGraph", "clearTrans", "clearDist", "clearValue",
                 "clearQ", "clearPolicy", "clearAll", "setValue_Cell",
                 "setPolicy_Cell", "setQ_Cell", "setTrans_Cell", "setDist_Cell"];
        self.dataCmds = ["setValue", "setPolicy", "setQ", "setTrans", "setDist", 
                         "setActProbs"];
#        self.dataRowCmds = ["setActProbs"];
        
    def executeCmd(self, sCmd):
        bFound = False;
        aCmdFn = sCmd.split("#");
        for i in range(len(aCmdFn)):
            if aCmdFn[i]!="":
                cmdFn = aCmdFn[i].split("(")[0];
                for j in range(len(self.allCmds)):
                    if cmdFn==self.allCmds[j]:
#                        print "self." + aCmdFn[i];
                        eval("self." + aCmdFn[i]);
                        bFound = True;
                        break;
                if not bFound:
                    for j in range(len(self.dataCmds)):
                        if cmdFn==self.dataCmds[j]:
#                            sData = str(aCmdFn[i])[len(cmdFn)+1:len(aCmdFn[i])-1];
                            sCmdFn = str(aCmdFn[i]);
                            sData = sCmdFn[sCmdFn.index("r'")+2:len(sCmdFn)-2];
                            self.receivedData = pickle.loads(sData);
#                            sData = sData.replace("'","@").replace("\n","$").replace("\"","#").replace("`","&");
                            sCmdParams = sCmdFn[0:sCmdFn.index("r'")];
#                            print "sData:", sData;
#                            print "sCmdParams:", sCmdParams;
                            eval(str("self." + sCmdParams + "r'')"));
                            bFound = True;
                            break;
#                if not bFound:
#                    for j in range(len(self.dataRowCmds)):
#                        if cmdFn==self.dataRowCmds[j]:
#                            sData = str(aCmdFn[i])[len(cmdFn)+1:len(aCmdFn[i])-1];
#                            sData = sData.replace("'","@").replace("\n","$");
#                            eval(str("self." + cmdFn + "(" + sData + ")"));
#                            break;
    
    def animTrans(self, iFrom, iAct, iTo, nDelay, bReverse=False):        
        nAnim = QtCore.QEasingCurve.InBounce;
#        nDelay = self.parent.stTraceEvents.traceEvents.nDelay;
        self.graphView.animTrans(iFrom-1, iAct-1, iTo-1, nDelay, nAnim, bReverse);
    
    def setStateType(self, iState, sType):
        self.restore_All_StatesType();
        self.restore_All_ActionsType();
        nType = ["Normal", "Current", "Fatal", "Goal"].index(sType);
        self.graphView.setNode_StyleStatus(iState, nType);
        self.graphScene.updateScene();        
    
    def setActionType(self, iState, iAct, sType):
        self.restore_All_ActionsType();
        nType = ["Normal", "Current", "Risky", "Policy"].index(sType);
        self.graphView.setAction_StyleStatus(iState, iAct-1, nType);
        self.graphScene.updateScene();
        
    def restore_All_StatesType(self):
        tCol = self.dataModel.nDims + 3 + self.dataModel.nActions; #St-Type
        nSt = self.dataModel.nStates;
        for i in range(nSt):
            data = self.dataModel.stInfo[i][tCol];
            self.dataView.gridStInfo.refreshGraph(i, tCol, data);
            
    def restore_All_ActionsType(self):
        pCol = self.dataModel.nDims + 2; #Policy
        rCol = self.dataModel.nRiskActResCols-1; #Risk Action Column
        nSt = self.dataModel.nStates;
        for i in range(len(self.dataModel.riskActRes)):
            data = self.dataModel.riskActRes[i][rCol];
            self.dataView.gridRiskActRes.refreshGraph(i, pCol, data);
        for i in range(nSt):
            data = self.dataModel.stInfo[i][pCol];
            self.dataView.gridStInfo.refreshGraph(i, pCol, data);
    
    def setValue_Cell(self, iState, nVal):
        vCol = self.dataModel.nDims + 1;
        self.dataModel.stInfo[iState-1][vCol] = nVal;
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
    
    def setPolicy_Cell(self, iState, nPolicy):
        pCol = self.dataModel.nDims + 2;
        self.dataModel.stInfo[iState-1][pCol] = nPolicy;
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
    
    def setQ_Cell(self, iState, iAct, nQ):
        qCol = self.dataModel.nDims + 3 + iAct-1;
        self.dataModel.stInfo[iState-1][qCol] = nQ;
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
    
    def setTrans_Cell(self, iFrom, iAct, iTo, nProb):
        self.dataModel.stateTrans[iAct-1][iFrom-1][iTo-1] = nProb;
        self.dataView.gridStTrans.updateGrid();
    
    def setDist_Cell(self, iFrom, iTo, nDist):
        self.dataModel.stateDists[iFrom-1][iTo-1] = nDist;
        self.dataView.gridStDists.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def regenerateGraph(self):
        self.dataContainer.updateGraph();
        
    def rebuildActEdges(self, nSt, nAct):
        aProbs = self.dataModel.stateTrans[nAct-1][nSt-1];
        print aProbs;
        self.graphScene.rebuildActEdges(nSt, nAct, aProbs);
        self.dataContainer.updateSelectedGraphSettings();
        
    def setActProbs(self, nSt, nAct, aProbs):
        aProbs = self.receivedData
        self.dataModel.stateTrans[nAct-1][nSt-1] = aProbs;
        self.dataView.gridStTrans.updateGrid();
        self.rebuildActEdges(nSt, nAct);        
        
    def setValue(self, aVal):
        aVal = self.receivedData;
        vCol = self.dataModel.nDims + 1;
        for i in range(len(aVal)):
            self.dataModel.stInfo[i][vCol] = aVal[i];
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def setPolicy(self, aVal):
        aVal = self.receivedData;
        pCol = self.dataModel.nDims + 2;
        for i in range(len(aVal)):
            self.dataModel.stInfo[i][pCol] = int(aVal[i]);
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def setQ(self, aVal):
        aVal = self.receivedData;
        qCol = self.dataModel.nDims + 3;
        for i in range(len(aVal)):
            for j in range(len(aVal[0])):
                self.dataModel.stInfo[i][qCol+j] = aVal[i][j];
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def setDist(self, aVal):
#        print "Setting Dist!!!"
        aVal = self.receivedData;
        for i in range(len(aVal)):
            for j in range(len(aVal[0])):
                self.dataModel.stateDists[i][j] = aVal[i][j];
        self.dataView.gridStDists.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def setTrans(self, aVal):
        aVal = self.receivedData;
        for i in range(len(aVal)):
            for j in range(len(aVal[0])):
                for k in range(len(aVal[0][0])):
                    self.dataModel.stateTrans[i][j][k] = aVal[i][j][k];
        self.dataView.gridStTrans.updateGrid();
        self.graphScene.rebuildAllEdges(self.dataModel.stateTrans);
        self.dataContainer.updateSelectedGraphSettings();
        
    def showTrans(self, bShow=True):
        self.graphView.setEdgesVisible(bShow);
        self.graphScene.updateScene();
        
    def clearTrans(self):
        nAct = self.dataModel.nActions;
        nSt = self.dataModel.nStates;
        self.dataModel.stateTrans = pylab.zeros((nAct,nSt,nSt));
        self.dataView.gridStTrans.updateGrid();
        self.graphScene.rebuildAllEdges(self.dataModel.stateTrans);
        
    def clearDist(self):
        nSt = self.dataModel.nStates;
        self.dataModel.stateDists = pylab.zeros((nSt,nSt));
        self.dataView.gridStDists.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def clearValue(self):
        vCol = self.dataModel.nDims + 1;
        nSt = self.dataModel.nStates;
        for i in range(nSt):
            self.dataModel.stInfo[i][vCol] = 0;
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def clearPolicy(self):
        pCol = self.dataModel.nDims + 2;
        nSt = self.dataModel.nStates;
        for i in range(nSt):
            self.dataModel.stInfo[i][pCol] = 0;
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def clearQ(self):
        qCol = self.dataModel.nDims + 3;
        nSt = self.dataModel.nStates;
        nAct = self.dataModel.nActions;
        for i in range(nSt):
            for j in range(nAct):
                self.dataModel.stInfo[i][qCol+j] = 0;
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.graphScene.updateScene();
        
    def clearAll(self):
        self.clearTrans();
        self.clearDist();
        vCol = self.dataModel.nDims + 1;
        pCol = self.dataModel.nDims + 2;
        qCol = self.dataModel.nDims + 3;
        nSt = self.dataModel.nStates;
        nAct = self.dataModel.nActions;
        for i in range(nSt):
            self.dataModel.stInfo[i][vCol] = 0;
            self.dataModel.stInfo[i][pCol] = 0;
            for j in range(nAct):
                self.dataModel.stInfo[i][qCol+j] = 0;
        self.dataView.gridStInfo.updateGrid();
        self.dataContainer.updateBkgColors();
        self.restore_All_StatesType();
        self.restore_All_ActionsType();
        self.graphScene.updateScene();
        
        
            